#include <stdio.h>
#include <string.h>

#include <auratypes.h>
#include "module.h"
#include "peimage.h"

void Section::RelocAddr(Aura_UInt32 vAddr, Aura_UInt32 uOffset, Aura_UInt32 uType)
{
    Aura_UInt32  *pAddr;
    Aura_Int32   nTemp;

    assert(FALL_INTO(vAddr, m_uVAddr, m_uVSize));

    pAddr = (Aura_UInt32 *)(m_pOwner->m_uImageBase + vAddr);
    PTRACE("pAddr:                             0x%x. \n", pAddr);
    // Relocation
    switch (uType) {
        case IMAGE_REL_BASED_ABSOLUTE:
            /* Absolute : no fixup required */
            break;

        case IMAGE_REL_BASED_HIGH:
        case IMAGE_REL_BASED_HIGHADJ:
            /* High - (16-bits) relocate the high half of an address */
            nTemp = *((UINT16 *)pAddr) << 16;
            nTemp += uOffset;
            *((UINT16 *)pAddr) = (UINT16) (nTemp >> 16);
            break;

        case IMAGE_REL_BASED_LOW:
            /* Low - (16-bit) relocate the low half of an address */
            nTemp = *((INT16 *)pAddr);
            nTemp += uOffset;
            *((UINT16*) pAddr) = (UINT16) nTemp;
            break;

        case IMAGE_REL_BASED_HIGHLOW:
            *pAddr += uOffset;
            break;

        case IMAGE_REL_BASED_MIPS_JMPADDR:
            /* JumpAddress - (32-bits) relocate a MIPS jump address */
            nTemp = (*((Aura_PUInt32) pAddr) & 0x3ffffff) << 2;
            nTemp += uOffset;
            *((Aura_PUInt32) pAddr) = (*((Aura_PUInt32) pAddr) & ~0x3ffffff) |
                                ((nTemp >> 2) & 0x3ffffff);
            break;

        default:
            PTRACE("not support the relocate type 0x%08x\n", uType);
            assert(0);
    }

}

void Section::MemZero()
{
    assert(m_pOwner);
    memset((Aura_PVoid *)(m_pOwner->m_uImageBase+m_uVAddr), 0, m_uVSize);
}

void Section::MemCopy(void * p, int nSize)
{
    assert(m_pOwner);
    memcpy((Aura_PVoid *)(m_pOwner->m_uImageBase+m_uVAddr), p, nSize);
}

void Section::MemCopy(Aura_UInt32 uOffset, Aura_UInt32 uSize, void * p)
{
    assert(m_pOwner);
    memcpy((Aura_PVoid *)(m_pOwner->m_uImageBase+m_uVAddr+uOffset), p, uSize);
}

